package com.shawn.baseappbygroovydsl.ui.views

import android.annotation.SuppressLint
import android.content.Context.INPUT_METHOD_SERVICE
import android.os.Bundle
import android.view.MotionEvent
import android.view.View
import android.view.View.OnFocusChangeListener
import android.view.WindowInsets
import android.view.inputmethod.InputMethodManager
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.chad.library.adapter4.BaseQuickAdapter
import com.choryan.quan.videowzproject.extension.ExtensionView.hide
import com.choryan.quan.videowzproject.extension.ExtensionView.show
import com.shawn.baseappbygroovydsl.R
import com.shawn.baseappbygroovydsl.appInterface.IPopBtnActionListener
import com.shawn.baseappbygroovydsl.component.SoundPoolManager
import com.shawn.baseappbygroovydsl.pop.PopRedChat
import com.shawn.baseappbygroovydsl.ui.adapter.ChatContentListAdapter
import com.shawn.baseappbygroovydsl.ui.base.FragmentBase
import com.shawn.baseappbygroovydsl.ui.extension.ExtensionCommon.toast
import com.shawn.baseappbygroovydsl.ui.extension.ExtensionLog.log
import com.shawn.baseappbygroovydsl.utils.UtilFastClickAbort
import eee.drama.idea_chat.bean.MessageChatBean
import eee.drama.idea_chat.databinding.FragChatContentBinding
import kotlinx.coroutines.*
import kotlin.random.Random


class FragChatContent(layoutRes: Int = R.layout.frag_chat_content) : FragmentBase<FragChatContentBinding>(layoutRes),
    BaseQuickAdapter.OnItemChildClickListener<MessageChatBean>, IPopBtnActionListener {

    private lateinit var layoutManager: LinearLayoutManager
    private var job: Job? = null
    private var isShowNewsTips = false
    private var newsCount = 0

    private val contentType by lazy {
        val type = arguments?.getInt(KEY_GROUP_TYPE)
        type ?: RED_GROUP_1
    }

    private val title by lazy {
        val title = arguments?.getString(KEY_GROUP_TITLE)
        title
    }

    private val chatAdapter by lazy {
        val value = ChatContentListAdapter(this)
        value
    }

    private val popRedChat by lazy {
        val value = PopRedChat(requireContext())
        value.popBtnActionListener = this
        value
    }

    private val vmRed by lazy {
        val vm: VMChat = ViewModelProvider(requireActivity())[VMChat::class.java]
        vm
    }



    override fun statusBar() {}

    override fun initClick() {
        mBind.ivRefresh.setOnClickListener {
            if (UtilFastClickAbort.isFastClick()) {
                return@setOnClickListener
            }
            SoundPoolManager.showSound(R.raw.tap_button)
            vmRed.computeResult(false)
        }
        mBind.vCloseHolder.setOnClickListener {
            if (UtilFastClickAbort.isFastClick()) {
                return@setOnClickListener
            }
            SoundPoolManager.showSound(R.raw.tap_button)
            hideKeyboardIfNeeded()
            removeThis()
        }
        mBind.llNewsCount.setOnClickListener {
            if (UtilFastClickAbort.isFastClick()) {
                return@setOnClickListener
            }
            hideNewsTips()
            mBind.chatRv.scrollToPosition(chatAdapter.itemCount - 1)
        }
        mBind.etContent.onFocusChangeListener = OnFocusChangeListener { v, hasFocus ->
            if (hasFocus) {
                hideNewsTips()
            }
        }
    }

    override fun lazyLoad() {
        initView()
        initClick()
        initJob()
    }

    private fun initJob() {
        job = lifecycleScope.launch {
            withContext(Dispatchers.IO) {
                delay(2000)
            }
            while (true) {
                val randomDelay = Random.nextLong(3000, 6001)
                withContext(Dispatchers.IO) {
                    delay(randomDelay)
                }
                if (popRedChat.isShowing) {
                    continue
                }
                withContext(Dispatchers.Main) {
                    sendRandomMessage()
                }
            }
        }
    }

    private fun sendRandomMessage() {
        val size = 1
        if (isShowNewsTips) {
            mBind.llNewsCount.show()
            newsCount += size
            mBind.tvNewsCount.text = "${newsCount}条新消息"
        } else {
            newsCount = 0
            mBind.llNewsCount.hide()
        }
        vmRed.replyComments(size)
    }

    private fun hideNewsTips() {
        mBind.llNewsCount.hide()
        isShowNewsTips = false
    }

    private fun initView() {
        layoutManager = LinearLayoutManager(context, RecyclerView.VERTICAL, false)
        mBind.chatRv.layoutManager = layoutManager
        mBind.chatRv.adapter = chatAdapter
        val itemAnimator = DefaultItemAnimator()
        itemAnimator.addDuration = 500
        mBind.chatRv.itemAnimator = itemAnimator

        mBind.chatRv.clearOnScrollListeners()
        mBind.chatRv.addOnScrollListener(RecyclerViewOnScrollListener())
    }

    private fun initTitle() {
        val random = Random.nextInt(1000, 3000)
        val local = "西安"
        val title = if (title != null) {
            "${title}($random)"
        } else {
            "${local}红包群($random)"
        }
        mBind.tvTitle.text = title
    }

    @SuppressLint("ClickableViewAccessibility")
    override fun getData() {
        mBind.chatRv.setOnTouchListener { _, event ->
            if (event.action == MotionEvent.ACTION_DOWN) {
                hideKeyboardIfNeeded()
            }
            false
        }
        mBind.tvSend.setOnClickListener {
            val content = mBind.etContent.text.toString()
            if (content.isEmpty()) {
                "说点什么吧~~".toast()
                return@setOnClickListener
            }
            sendUserMessage(content)
        }
        mBind.root.setOnApplyWindowInsetsListener(object : View.OnApplyWindowInsetsListener {
            override fun onApplyWindowInsets(v: View, insets: WindowInsets): WindowInsets {
                mBind.chatRv.scrollToPosition(chatAdapter.itemCount - 1)
                return insets
            }
        })
        vmRed.userResultLiveData.observe(this) {
            initTitle()
            chatAdapter.submitList(it)
            mBind.chatRv.scrollToPosition(chatAdapter.itemCount - 1)
        }
        vmRed.replyCommentsLiveData.observe(this) {
            chatAdapter.addAll(it)
            if (!isShowNewsTips) {
                layoutManager.scrollToPositionWithOffset(chatAdapter.itemCount - 1, 0)
            }
        }
        vmRed.initUserGroup(contentType)
    }

    override fun getBind(view: View): FragChatContentBinding {
        return FragChatContentBinding.bind(view)
    }

    private fun sendUserMessage(message: String) {
        mBind.etContent.text = null
        val beanUser = MessageChatBean(
            icon = "",
            name = "游客",
            msg = message,
            itemType = ChatContentListAdapter.ITEM_TYPE_USER
        )
        chatAdapter.add(beanUser)
        mBind.chatRv.scrollToPosition(chatAdapter.itemCount - 1)
    }

   override fun onKeyCodeBack(): Boolean {
        hideKeyboardIfNeeded()
        if (popRedChat.isShowing) {
            return true
        }
        removeThis()
        return true
    }

    private fun removeThis() {
        job?.cancel()
        job = null
        removeFullScreenFrag(FragChatContent::class.java.name)
    }

    private fun hideKeyboardIfNeeded() {
        val imm = activity?.getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager?
        imm?.hideSoftInputFromWindow(mBind.etContent.windowToken, 0)
    }

    private var clickPos = 0

    override fun onItemClick(
        adapter: BaseQuickAdapter<MessageChatBean, *>,
        view: View,
        position: Int
    ) {
        if (adapter is ChatContentListAdapter) {
            val bean = adapter.getItem(position)
            bean?.let { _bean ->
                if (!bean.isClick && isItemClick(bean)) {
                    clickPos = position
                    popRedChat.show(mBind.root, bean)
                }
            }
        }
    }

    private fun isItemClick(bean: MessageChatBean): Boolean {
        return bean.itemType == ChatContentListAdapter.ITEM_TYPE_RED_STYLE_0 ||
                bean.itemType == ChatContentListAdapter.ITEM_TYPE_RED_STYLE_1 ||
                bean.itemType == ChatContentListAdapter.ITEM_TYPE_RED_STYLE_2
    }

    override fun onPopActionClick(position: String, params: Any?) {
        if (!isAdded) {
            return
        }
        when (position) {
            "normal_get",
            "normal_close" -> {

            }
            PopRedChat.POP_RED_CHAT_GET -> {
                popRedChat.dismiss()
                activity?.let {

                }
            }
        }
    }

    inner class RecyclerViewOnScrollListener : RecyclerView.OnScrollListener() {
        override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
            super.onScrollStateChanged(recyclerView, newState)
            if (newState == RecyclerView.SCROLL_STATE_IDLE && chatAdapter.itemCount > 0) {
                val firstItemPosition: Int = layoutManager.findFirstVisibleItemPosition()
                val lastItemPosition: Int = layoutManager.findLastVisibleItemPosition()
                "onScrollStateChanged firstItemPosition=$firstItemPosition    lastItemPosition=$lastItemPosition".log()
                isShowNewsTips = lastItemPosition < chatAdapter.itemCount - 2
                if (!isShowNewsTips) {
                    mBind.llNewsCount.hide()
                }
            }
        }
    }

    companion object {
        const val REWARD_LOCATION_POP_RED = "pop_red_content"
        const val KEY_GROUP_TYPE = "key_group_type"
        const val KEY_GROUP_TITLE = "key_group_title"

        const val RED_GROUP_1 = 1
        const val RED_GROUP_2 = 2
        const val RED_GROUP_3 = 3
        const val RED_GROUP_DRAMA = 4
        fun newInstance(type: Int,title:String): FragChatContent {
            val args = Bundle()
            val fragment = FragChatContent()
            args.putInt(KEY_GROUP_TYPE, type)
            args.putString(KEY_GROUP_TITLE,title)
            fragment.arguments = args
            return fragment
        }
    }
}